package craky.keeper.util;

import java.io.File;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Criterion;

import craky.keeper.KeeperConst;

public class HibernateUtil
{
	private static final SessionFactory sessionFactory;
	
	static
	{
		try
		{
		    Configuration config = new Configuration().configure(new File(KeeperConst.HIBERNATE_CONFIG_PATH));
			sessionFactory = config.buildSessionFactory();
		}
		catch(Throwable e)
		{
			throw new ExceptionInInitializerError(e);
		}
	}
	
	public static final ThreadLocal<Session> session = new ThreadLocal<Session>();
	
	public static SessionFactory getSessionFactory()
	{
		return sessionFactory;
	}
	
	public synchronized static Session currentSession() throws HibernateException
	{
		Session s = (Session)session.get();
		
		if(s == null || !s.isOpen())
		{
			s = sessionFactory.openSession();
			session.set(s);
		}
		
		return s;
	}
	
	public static void closeSession() throws HibernateException
	{
		Session s = (Session)session.get();
		session.set(null);
		
		if(s != null)
		{
			s.close();
		}
	}
	
    public static List<?> getDatas(Class<?> clazz, Criterion...criterions)
    {
        Session session = currentSession();
        Criteria crit = session.createCriteria(clazz);

        if(criterions != null && criterions.length > 0)
        {
            for(Criterion criterion: criterions)
            {
                crit = crit.add(criterion);
            }
        }

        List<?> datas = crit.list();
        closeSession();
        return datas;
    }
	
    public static void insert(Object obj)
    {
        Session session = currentSession();
        Transaction tx = session.beginTransaction();
        session.save(obj);
        tx.commit();
        closeSession();
    }
	
	public static void delete(Object obj)
    {
        Session session = currentSession();
        Transaction tx = session.beginTransaction();
        session.delete(obj);
        tx.commit();
        closeSession();
    }
	
	public static void update(Object obj)
	{
        Session session = currentSession();
        Transaction tx = session.beginTransaction();
        session.update(obj);
        tx.commit();
        closeSession();
	}
}